
# include <WiFi.h>
#include <SPI.h>
#include <RDA5807.h>
#include <U8g2lib.h>
#include <Ticker.h>


int oldsec = -1; 
int buttonFlag = 0;



//fm radio
#define ESP32_I2C_SDA 5
#define ESP32_I2C_SCL 4
#define MAX_DELAY_RDS 40      // 40ms - polling method
#define MAX_STATIONS 10       // 电台数量上限
uint8_t stations = 0;         // 选中的电台index
long rds_elapsed = millis();
uint8_t fmvol = 6;            // 音量控制变量
RDA5807 rx;                   // 收音机对象

uint16_t fmstation[MAX_STATIONS] = {0}; //电台列表


void fmInit() {
    Wire.begin(ESP32_I2C_SDA, ESP32_I2C_SCL);
    rx.setup();
    rx.setVolume(fmvol);
}

// 找到后台寻找信号最好的频段
uint16_t findMaxSing(uint16_t freq, uint16_t rssi) {
    while (rx.isStereo()) {
        rx.setFrequencyUp();
        delay(100);
        if (rx.isStereo() && rx.getRssi() > rssi) {
            freq = rx.getFrequency();
            rssi = rx.getRssi();
        }
    }
    return freq;
}


void searchFM() {
    uint16_t i = 0;
    uint8_t num = 0;
    rx.setFrequency(8700); // 从8700MHZ开始扫描
    while (i < 210) {
        delay(100);
        if (rx.isStereo() && rx.getRssi() > 20) { //如果搜索不到台, 切换信号值大于35
            fmstation[num++] = findMaxSing(rx.getFrequency(), rx.getRssi());
            Serial.print("Good Frequency: ");
            Serial.println(rx.getFrequency());
            if (num >= MAX_STATIONS) return ; // 根据固定的值搜索电台
        }
        rx.setFrequencyUp();
        i++;
        Serial.print("Search FM");
        Serial.print(rx.getFrequency());
        Serial.print(":");
        Serial.println(rx.getRssi() );
    }
    for (i = 0; i<MAX_STATIONS; i++) {
        Serial.print(fmstation[i]);
        Serial.println("");
    }
    // Serial.println("End Search");
}

void changeStation() {
  while (1) {
    if (stations == MAX_STATIONS - 1) {
      stations = 0;
      rx.setFrequency(fmstation[stations]);
      //Serial.println(fmstation[stations]);
      return;
    }
    if (fmstation[stations + 1] != 0) {
      rx.setFrequency(fmstation[stations + 1]);
      stations++;
      Serial.println(fmstation[stations]);
      return;
    }
    stations++;
  }
}

void SetFMFrequency() {
    //设置频率
    rx.setFrequency(fmstation[stations]);
}
//fm radio end

//web radio
String IPAddress;
uint16_t num=0;
#define WEBSERVERIP "192.168.1.55"
// #define WEBSERVERIP "172.20.10.5"
#define WEBSERVERPORT 3999
uint8_t netbuf[3][1024];      //网络数据缓冲区
uint16_t writep = 0;          //写入数量
uint16_t readp = 0;           //读取数量
WiFiClient client; //声明一个客户端对象，用于与服务器进行连接
bool connstat = false;        //连接状态
bool iswaitecho = false;      //是否等待服务器回应
Ticker flipper;               //时间中断
uint16_t m_offset = 0;

void onTimer(void) {
  if(readp<=writep)  dacWrite(17, netbuf[readp % 3][m_offset++]);      //播放一次声音
  if (m_offset >= 1024) {
    m_offset = 0;
    readp++;      //读取完成一个缓冲区
  }
}
bool connNetMusic() {
  uint8_t i = 0;
  while (i < 5) { //最多连接5次
    if (client.connect(WEBSERVERIP, WEBSERVERPORT)) {
      connstat = true;
      Serial.println("连接成功");
      return true;
    } else {
      Serial.println("访问失败");
      client.stop(); //关闭客户端
    }
    i++;
    delay(100);
  }
  return false;
}

void playMusic() {
        digitalWrite(41, HIGH);digitalWrite(42, HIGH);
        if (connstat == true){

            if (iswaitecho == false && (writep - readp) < 2) {
                client.write('n');          //申请一个缓冲片
                iswaitecho = true;
            }
            if(writep%120==0) displayMessage();        //降低刷新屏幕频率
            if (client.available()) { //如果有数据可读取
                num = client.read(netbuf[writep % 3], 1024);
                if (writep == 0 && readp == 0) {
                    flipper.attach(0, onTimer);     //开启定时中断 就是每秒中断20000次
                }
                writep++;
                iswaitecho = false;
            }
        }
        else{
            //一旦网络连接开始播放音乐，
            displayMessage();
        }
}
//web end



uint8_t countStation() {
  uint8_t i;
  for (i = 0; i < MAX_STATIONS; i++) {
    if (fmstation[i] == 0) return i;
  }
  return i;
}

//输出控制


// 功能控制
int curr_sour = 0;    // 选择的功能, 0为显示日期, 1为FM 收音机, 2为Web 收音机
#define button1 1
#define button2 2
#define button3 3
#define button4 6

// void FaceChange(){
//     // 切换不同的状态
//     if (buttonFlag == 1) { 
//         curr_sour = (curr_sour+1)%3;
//     }
// }

void FunctionUp() {
    if (buttonFlag == 1) { 
        // 如果是按键1, 修改功能
        curr_sour = (curr_sour+1)%3;
    }
    if (curr_sour == 0) {
        //Date 功能, 没有特别的操作, 需要关闭网络收音机的客户端
        Serial.println("info: Datetime Page");
        digitalWrite(41, LOW);digitalWrite(42, LOW);
        client.write('q');
        client.stop(); //关闭客户端
        flipper.detach();
        connstat = false;
    }
    else if (curr_sour == 1 ) {
        //收音机, 只需要打开收音机的开关即可
        Serial.println("info: FM Radio Page");
        digitalWrite(41, HIGH); digitalWrite(42, LOW);
        if (buttonFlag == 2) {
            changeStation();
        }
    }
    else if (curr_sour == 2) {
        // net radio 网络收音机, 需要启动收音机的开关
        Serial.println("info: Net Radio Page");
        digitalWrite(41, HIGH);digitalWrite(42, HIGH);
        connNetMusic();
    }
}

// 输出控制结束

// monitor

U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 36, /* data=*/ 35, /* cs=*/ 46, /* dc=*/ 33, /* reset=*/ 34);

void mointorInit() {
    u8g2.begin();
}

void displayWelcome() { // 欢迎画面, 显示John Radio
  u8g2.firstPage();
  u8g2.clearBuffer();         //清屏
  u8g2.setFontDirection(0);   
  u8g2.setFont(u8g2_font_ncenB14_tr); //使用大字体
  u8g2.setCursor(0, 34);
  u8g2.print("John  Radio");
  u8g2.sendBuffer();          //
}

void displayMessage() { //每次刷新oled
    struct tm timeinfo;
    char str[64] = {0};
    if (!getLocalTime(&timeinfo)) {
        Serial.println("error: can'get time");
        return;
    }
    // 输出时间
    if (oldsec == timeinfo.tm_sec) return ;
    oldsec = timeinfo.tm_sec;
        // 显示其他信息
    u8g2.setFont(u8g2_font_ncenB08_tr);
    if (curr_sour == 0) { //静音模式
        u8g2.clearBuffer();
        u8g2.setFontDirection(0);
        // u8g2.setFont(u8g2_font_ncenB18_tr);
        u8g2.setCursor(10,20);
        u8g2.print(&timeinfo, "%H:%M:%S");


        u8g2.setCursor(30,36);
        u8g2.print(&timeinfo, "%Y/%m/%d");
        u8g2.setCursor(40,50);
        u8g2.print("Datetime");
        u8g2.setCursor(30, 64);
        // u8g2.print(IPAddress.c_str()); //显示IP
    } else if (curr_sour == 1) { // FM 模式
        u8g2.clearBuffer();
        u8g2.setCursor(10,20);
        // sprintf(str, "FM:%d/%d       Vol:%02d/%d", stations + 1, countStation(), fmvol, 15);
        // sprintf(str, "FM:%d/%d       Vol:%02d/%d", stations + 1, countStation(), fmvol, 15);
        // u8g2.print(str);
        sprintf(str, "Fequencey: %d", fmstation[stations] );
        u8g2.print(str);
        u8g2.setCursor(18,60);
        u8g2.print("SW2 change Feq");

    }else if (curr_sour == 2) { //网络收音机模式
        if (connstat == true) {
            u8g2.clearBuffer();
            u8g2.setCursor(10,20);
            u8g2.print("NetRadio");
            u8g2.setCursor(38, 46);
            sprintf(str, "%s:%d", WEBSERVERIP, WEBSERVERPORT);
            u8g2.print(str);        
            // u8g2.print("Connection failed.");
        }else {
            u8g2.clearBuffer();
            u8g2.setCursor(38, 46);
            u8g2.print("NetRadio");
            u8g2.setCursor(20, 60);
            // sprintf(str, "%s:%d", WEBSERVERIP, WEBSERVERPORT);
            u8g2.print("Connection failed.");
        }
    }
    u8g2.sendBuffer();

}
// monitor end

//wifi
// const char* SSID = "JohniPhone";
// const char* PASSWD = "88887777";
const char* SSID     = "HUAWEI-B311-B482";
const char* PASSWD = "147258369";
const char *ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 8 * 3600;
const int daylightOffset_sec = 0;


String WifiConnecttion() {
    WiFi.mode(WIFI_STA);
    WiFi.begin(SSID, PASSWD);
    while (WiFi.status() != WL_CONNECTED) {
        delay(400); 
   }
   return WiFi.localIP().toString();
}
//wifi end

void setup() {
    // put your setup code here, to run once:
    pinMode(41, OUTPUT);
    pinMode(42, OUTPUT);

    digitalWrite(41, LOW);
    digitalWrite(42, LOW);
    Serial.begin(115200);
    mointorInit(); // 初始化屏幕
    displayWelcome(); // 显示欢迎
    Serial.println("connect wifi");
    IPAddress = WifiConnecttion();
    Serial.println(IPAddress.c_str());
    fmInit();
    searchFM();
    SetFMFrequency();
    configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); //使用官方configTime方法获取时间
    pinMode(button1, INPUT_PULLUP); 
    pinMode(button2, INPUT_PULLUP);
    pinMode(button3, INPUT_PULLUP);
    pinMode(button4, INPUT_PULLUP);

}

void loop() {
    num=0;
    displayMessage();
    if (digitalRead(button1) == LOW) {
        delay(50);
        if (digitalRead(button1) == LOW) {
            buttonFlag = 1;
        }
    }
    if (digitalRead(button2) == LOW) {
        delay(50);
        if (digitalRead(button2) == LOW) {
            buttonFlag = 2;
        }
    }
    if (digitalRead(button3) == LOW) {
        delay(50);
        if (digitalRead(button3) == LOW) {
            buttonFlag = 3;
        }
    }
    if (digitalRead(button4) == LOW) {
        delay(50);
        if (digitalRead(button4) == LOW) {
            buttonFlag = 4;
        }
    }
    if (buttonFlag != 0) {
        FunctionUp();
        delay(1000);
    }
    if (curr_sour == 2) {
        playMusic();
    }
    buttonFlag = 0;
}
